/**************************************************************************
 * @doc PROTOCOL
 * @module PROTFUNC.C | Protocol table functions
 *
 * Product     :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   SoftPay Development Team (I_SP2000).
 * <nl>Notes       :
 *
 * @head3 PROTOCOL Functions |
 * @index | PROTOCOL
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 $Log: /SoftPay/SPK2SIM/Source/Protocol/protfunc.c $
 ********************************************************************************/
#include <project.h>

#ifdef PET_DEFINED

#define PROTFUNC_C

#include <stdio.h>
#include <ascii.h>
#include <acldev.h>
#include <aclstr.h>
#include <aclascii.h>
#include <aclconio.h>
#include <xmodem.h>
#include <string.h>

#include <define.h>
#include <comm.h>
#include <funcids.h>
#include <msgfuncs.h>
#include <mdmdefs.h>
#include <modem.h>
#include <modemmsg.h>
#include <table.h>
#include <ui.h>
#include <packet.h>
#include <protomsg.h>
#include <protfunc.h>
#include <protocol.h>
#include <isoproto.h>
#include <SPDebug.h>

/*********************************************************************************************
* @func int | inSetProtoError |
*       Forces a VS_ERROR so the protocol engine gets it and returns an error as well
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/
int inSetProtoError(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    if (pobProtocol->fContinue) {
        pobProtocol->fError = VS_FALSE;
        return(VS_SUCCESS);
    }
    pobProtocol->fError = VS_TRUE;
    return(VS_ERROR);
}
/*********************************************************************************************
* @func int | inReceiveAnyChar |
*       Reads a single character from the modem
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inReceiveAnyChar(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inLength;
    int inTimeout;

    /* calc required for ACT library function (xmdm_receive_data)*/
    inTimeout = pobProtocol->srPET.shTimeOut * 100;
    if ((inLength = obCommunication.inReceive(&obCommunication, &pobProtocol->chChar, 1, inTimeout, RECEIVING_MSG21)) < 0)
        return(VS_ERROR);

    if (inLength == 1)
        pobProtocol->fError = VS_FALSE;
    else
        pobProtocol->fError = VS_TRUE;

    pobPacket->pchReceiveBuff[0] = pobProtocol->chChar;
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inCheckPacketLRC |
*       Check the response packet's LRC
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inCheckPacketLRC(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inSize;
    unsigned int uiLRCChar;
    char* pchSourceBuffer;


    // pdebug(("--inCheckPacketLRC--"));
    pchSourceBuffer = (char *) pobPacket->pchReceiveBuff;
    inSize = pobPacket->inReceiveSize - 1;

    if (*pchSourceBuffer == STX) {
        pchSourceBuffer++;
        inSize--;
    }

    uiLRCChar = SVC_CRC_CALC(0, pchSourceBuffer, inSize);

    /* LRC is LSB of uiLRCChar */
    if (uiLRCChar == pobPacket->pchReceiveBuff[pobPacket->inReceiveSize - 1])
        pobProtocol->fError = VS_FALSE;
    else
        pobProtocol->fError = VS_TRUE;

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inReceiveChar |
*       Checks the response for the character in the parameter of the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inReceiveChar(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    // pdebug(("--inReceiveChar--"));

    do {
        if (inReceiveAnyChar(pobProtocol, pobPacket)) {
            // pdebug(("ReceiveAny Error"));
            return(VS_ERROR);
        }
    } while ((char) pobProtocol->srPET.shParameter != pobProtocol->chChar);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inReceivePacket |
*       Reads the response packet from the modem
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inReceivePacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inBytesRead,
    inAdjustedBufferSize;
    unsigned char * pchEndOfBuffer;
    char chEndOfPacket;
    char chCounter = 0;
    char szStatusMsg[MESSAGE_SIZE];
    int inTimeout;

    // pdebug(("--inReceivePacket--"));

    if (!obCommunication.inReceive)
        return(VS_SUCCESS);

    pobPacket->inReceiveSize = 0;
    pchEndOfBuffer = pobPacket->pchReceiveBuff;
    inAdjustedBufferSize = pobPacket->inReceiveBuffSize;

    vdGetMessageFromThisFile(PROTOCOL_MSG_FILE, WAITING_FOR_RESPONSE_MSG, szStatusMsg);
    vdDisplayStatusString(szStatusMsg);
    /* calc required for ACT library function (xmdm_receive_data)*/
    inTimeout = pobProtocol->srPET.shTimeOut * 100;

    do {
        if ((inBytesRead = obCommunication.inReceive(&obCommunication, (char *) pchEndOfBuffer, inAdjustedBufferSize, inTimeout, RECEIVING_MSG21)) < 0)
            return(VS_ERROR);
        pobPacket->inReceiveSize += inBytesRead;
        pchEndOfBuffer += inBytesRead;
        *pchEndOfBuffer = 0;
        if (pobPacket->inReceiveSize > 2) {
            switch (pobProtocol->srPET.shParameter) {
            case STX_ETX_LRC:
                chEndOfPacket = ETX;
                break;
            case STX_ETB_LRC:
                chEndOfPacket = ETB;
                break;
            case SI_SO_LRC:
                chEndOfPacket = SO;
                break;
            default:
                return(VS_SUCCESS);
            }
            if (pobPacket->pchReceiveBuff[pobPacket->inReceiveSize - 2] == chEndOfPacket)
                return(VS_SUCCESS);
        }

        inAdjustedBufferSize -= inBytesRead;

        // pdebug(("Counter=%d",chCounter++));
    } while (1);
}

/*********************************************************************************************
* @func int | inReceiveHotelLanPacket |
*       Reads the response packet from the LAN
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inReceiveHotelLanPacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inBytesRead;
    char chCounter = 0;
    char szStatusMsg[MESSAGE_SIZE];
    int inTimeout;


    // pdebug(("--inReceiveHotelLanPacket--"));

    if (!obCommunication.inReceive)
        return(VS_SUCCESS);

    pobPacket->inReceiveSize = 0;

    vdGetMessageFromThisFile(PROTOCOL_MSG_FILE, WAITING_FOR_RESPONSE_MSG, szStatusMsg);
    vdDisplayStatusString(szStatusMsg);

    /* calc required for ACT library function (xmdm_receive_data)*/
    inTimeout = pobProtocol->srPET.shTimeOut * 100;
    do {
        if ((inBytesRead = obCommunication.inReceive(&obCommunication, (char *) pobPacket->pchReceiveBuff, pobPacket->inReceiveBuffSize, inTimeout, RECEIVING_MSG21)) < 0)
            return(VS_ERROR);

        pobPacket->inReceiveSize = inBytesRead;
        return VS_SUCCESS;
    } while (1);
}

/*********************************************************************************************
* @func int | inSendAChar |
*       Sends the character in the parameter field of the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inSendAChar(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    char szScratch[1];

    MEMCLR(szScratch, sizeof(szScratch));
    if (obCommunication.fLinkUp != VS_TRUE)
        return(VS_ERROR);

    sprintf(szScratch, "%c", pobProtocol->srPET.shParameter);
    if (obCommunication.inSend(&obCommunication, szScratch, 1, VS_FALSE, SEND_COMM_TIMEOUT, TRANSMITTING_MSG21) < 0) {
        pobProtocol->fError = VS_TRUE;
        return(VS_ERROR);
    }
    pobProtocol->fError = VS_FALSE;
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inMakePacket |
*       Using the inPack routine in the packet object, creates the request packet.
*       The packet type is assigned from the parameter field in the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inMakePacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    // pdebug(("--inMakePacket--"));
    //  pobPacket->fError = 0;
    pobPacket->inType = pobProtocol->srPET.shParameter;
    pobPacket->fError = VS_FALSE;

    if (pobPacket->inPack(pobPacket) != VS_SUCCESS) {
        pobProtocol->fError = VS_TRUE;
        return(VS_ERROR);
    }

    //BT_REQUEST_TRACE('B', pobPacket->pchSendBuff, pobPacket->inSendSize);


    pobPacket->pchSendBuff[pobPacket->inSendSize] = '\0';
    pobProtocol->fError = pobPacket->fError;

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inFramePacket |
*       Frames the packet with the parameter field of the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inFramePacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    // pdebug(("--inFramePacket--"));
    switch (pobProtocol->srPET.shParameter) {
    case STX_ETX_LRC :
        insert_char((char *) pobPacket->pchSendBuff, 0, STX);
        pobPacket->inSendSize++;
        append_char((char *) pobPacket->pchSendBuff, ETX);
        pobPacket->inSendSize++;
        break;
    case STX_ETB_LRC :
        insert_char((char *) pobPacket->pchSendBuff, 0, STX);
        pobPacket->inSendSize++;
        append_char((char *) pobPacket->pchSendBuff, ETB);
        pobPacket->inSendSize++;
        break;
    case SI_SO_LRC :
        insert_char((char *) pobPacket->pchSendBuff, 0, SI);
        pobPacket->inSendSize++;
        append_char((char *) pobPacket->pchSendBuff, SO);
        pobPacket->inSendSize++;
        break;
    case SOH_ETX_LRC :
        insert_char((char *) pobPacket->pchSendBuff, 0, SOH);
        pobPacket->inSendSize++;
        append_char((char *) pobPacket->pchSendBuff, ETX);
        pobPacket->inSendSize++;
        break;
    default:
        break;
    }

    append_char((char *) pobPacket->pchSendBuff, SVC_CRC_CALC(0, (char *) pobPacket->pchSendBuff + 1, pobPacket->inSendSize));
    pobPacket->inSendSize++;

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inDeFramePacket |
*       Removes the starting and ending characters in the packet identified by
*       the parameter field of the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inDeFramePacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    char chCharacter;

    // pdebug(("--inDeFramePacket--"));
    if (!pobProtocol->srPET.shParameter)
        return(VS_SUCCESS);

    switch (pobProtocol->srPET.shParameter) {
    case STX_ETX_LRC :
    case STX_ETB_LRC :
        chCharacter = STX;
        break;
    case SI_SO_LRC :
        chCharacter = SI;
        break;
    }

    if (purge_char((char *) pobPacket->pchReceiveBuff, chCharacter))
        pobPacket->inReceiveSize--;

    switch (pobProtocol->srPET.shParameter) {
    case STX_ETX_LRC :
        chCharacter = ETX;
        break;
    case STX_ETB_LRC :
        chCharacter = ETB;
        break;
    case SI_SO_LRC :
        chCharacter = SO;
        break;
    }

    if (purge_char((char *) pobPacket->pchReceiveBuff, chCharacter))
        pobPacket->inReceiveSize--;

    /* Remove LRC */
    pobPacket->inReceiveSize--;
    pobPacket->pchReceiveBuff[pobPacket->inReceiveSize] = 0;

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inSendPacket |
*       Sends the request packet using the timeout value from the state record.
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inSendPacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    char szStatusMsg[MESSAGE_SIZE];
    // pdebug(("--inSendPacket--"));

    vdGetMessageFromThisFile(PROTOCOL_MSG_FILE, SENDING_REQUEST_MSG, szStatusMsg);
    vdDisplayStatusString(szStatusMsg);

    // pdebug(("snd2:%d", pobPacket->pchSendBuff[0]));

    if (pobPacket->pchSendBuff[0] == NAK)
        pobPacket->pchSendBuff[0] = SOH;

    if (obCommunication.inSend(&obCommunication, (char *) pobPacket->pchSendBuff, pobPacket->inSendSize, VS_TRUE, SEND_COMM_TIMEOUT, TRANSMITTING_MSG21) < 0)
        return(VS_ERROR);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inResetCounter |
*       Sets the protocol object counter in the parameter field to 0.
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inResetCounter(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    pobProtocol->srCounters[pobProtocol->srPET.shParameter].shCount = 0;
    pobProtocol->fError = VS_FALSE;
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inIncrementCounter |
*       Increments the protocol object counter in the parameter field
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inIncrementCounter(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    pobProtocol->srCounters[pobProtocol->srPET.shParameter].shCount++;
    pobProtocol->fError = VS_FALSE;
    return(VS_SUCCESS);
}
/*********************************************************************************************
* @func int | inBranchOnChar |
*       Compares the char in the protocol object with the parameter in the state record
*       Sets the error flag to false if the characters are the same
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inBranchOnChar(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    // pdebug (("Branch On Char %x", pobProtocol->chChar));
    // pdebug(("snd:%d", pobPacket->pchSendBuff[0]));

    if (pobProtocol->chChar == (char) pobProtocol->srPET.shParameter)
        pobProtocol->fError = VS_FALSE;
    else
        pobProtocol->fError = VS_TRUE;
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inResetRecordNumber |
*       Sets the record number in the packet object to 0
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inResetRecordNumber(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    pobPacket->inRecord = 0;
    pobPacket->fEOF = VS_FALSE;
    return(VS_SUCCESS);
}
/*********************************************************************************************
* @func int | inIncrementRecordNumber |
*       Increments the record number in the packet object
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inIncrementRecordNumber(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    pobPacket->inRecord++;
    return(VS_SUCCESS);
}
/*********************************************************************************************
* @func int | inTestRecordNumber |
*       Compares the record number in the packet object to the
*       parameter in the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inTestRecordNumber(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    if (pobPacket->inRecord == pobProtocol->srPET.shParameter)
        pobProtocol->fError = VS_FALSE;     /* Tests, if TRUE, return FALSE for consistency of PET */
    else
        pobProtocol->fError = VS_TRUE;

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inEndofBatch |
*       Sets the End of file flag in the packet object
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inEndofBatch(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    if (pobPacket->fEOF)
        pobProtocol->fError = VS_FALSE;     /* Tests, if TRUE, return FALSE for consistency of PET */
    else
        pobProtocol->fError = VS_TRUE;

    pobPacket->fEOF = VS_FALSE;
    return(VS_SUCCESS);
}
/*********************************************************************************************
* @func int | inDismantlePacket |
*       Using the inUnpack routine in the packet object, read the response packet.
*       The packet type is assigned from the parameter field in the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inDismantlePacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    // pdebug(("--inDismantlePacket--"));
    pobPacket->inType = pobProtocol->srPET.shParameter;
    if (pobPacket->inUnpack(pobPacket) != VS_SUCCESS) {
        pobProtocol->fError = VS_TRUE;
        return(VS_ERROR);
    }


    //  BT_RESPONSE_TRACE('B', pobPacket->pchReceiveBuff, pobPacket->inReceiveBuffSize);

    pobProtocol->fError = pobPacket->fError;
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inClearRecvBuff |
*      Continuously reads a character out of the receive buffer until there are no more.
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inClearRecvBuff(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inTimeout;

    // pdebug(("--inClearRecvBuff--"));

    /* calc required for ACT library function (xmdm_receive_data)*/
    inTimeout = pobProtocol->srPET.shTimeOut * 100;

    while (obCommunication.inReceive(&obCommunication, &pobProtocol->chChar, 1, inTimeout, RECEIVING_MSG21));
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inPause |
*       Display message, beep and wait for key press
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inPause(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    char szMessage[MESSAGE_SIZE + 1];

    vdGetMessageFromThisFile(PROTOCOL_MSG_FILE, PROTOCOL_PAUSED_MSG, szMessage);
    vdDisplayStatusString(szMessage);

    sprintf(szMessage, "%d", pobProtocol->shIndex);
    vdDispStrAtRight(szMessage, obDisp.inStatusLine, NO_CLEAR);
    beep(C_ERROR);
    get_char();
    vdClearStatusMessage();

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inEndOfDownload |
*       Copies the end of download flag in the protocol object to the error flag
*       and sets the end of download flag to False.
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inEndOfDownload(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    pobProtocol->fError = pobPacket->fEOD;
    pobPacket->fEOD = VS_FALSE;

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inAnalysePacket |
*       Using the inAnalyse routine in the packet object, analyse the response packet.
*       The packet type is assigned from the parameter field in the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inAnalysePacket(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    char szStatusMsg[MESSAGE_SIZE];
    int inResult;
    char szResp[RESP_MSG_SIZE + 1];
    TRANSACTION_OBJECT* pobTran;



    pobTran = (TRANSACTION_OBJECT *) pobPacket->Transaction;

    // pdebug(("--inAnalysePacket--"));
    pobPacket->inType = pobProtocol->srPET.shParameter;
    pobPacket->fError = VS_FALSE;

    vdGetMessageFromThisFile(PROTOCOL_MSG_FILE, ANALYSING_RESPONSE_MSG, szStatusMsg);
    vdDisplayStatusString(szStatusMsg);

    inResult = pobPacket->inAnalyse(pobPacket);



    if (inResult == VS_ERROR)
        return(VS_ERROR);

    vdGGRespMsg(szResp);
    //  BT_TRACE ('H', szResp);

    if (inResult == CONTINUE)
        pobProtocol->fContinue = VS_TRUE;



    /* VS_SUCCESS */
    pobProtocol->fError = pobPacket->fError;



    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inTimeOutReceiveAnyChar |
*       Checks if the error was a TimeOut
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inTimeOutReceiveAnyChar(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inLength;
    int inTimeout;

    // pdebug (("--TimeOutReceiveAnyChar--"));

    /* calc required for ACT library function (xmdm_receive_data)*/
    inTimeout = pobProtocol->srPET.shTimeOut * 100;
    if ((inLength = obCommunication.inReceive(&obCommunication, &pobProtocol->chChar, 1, inTimeout, RECEIVING_MSG21)) < 0) {
        if (inLength != E_HR_TIMEOUT)            /* Do not do when TimeOut was reached : E_HR_TIMEOUT */
            return(VS_ERROR);
    }

    if (inLength != E_HR_TIMEOUT)                /* No TimeOut */
        pobProtocol->fError = VS_FALSE;  /* Next State for any char */
    else
        pobProtocol->fError = VS_TRUE;  /* Error State for time out */
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inGiveErrorReceiveAnyChar |
*       Sets the error flag if there is a No Carrier error when
*       reading the receive buffer
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/
int inGiveErrorReceiveAnyChar(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inLength;
    char strAux[256];
    int inTimeout;


    // pdebug (("--GiveErrorReceiveAnyChar--"));

    /* calc required for ACT library function (xmdm_receive_data)*/
    inTimeout = pobProtocol->srPET.shTimeOut * 100;
    strAux[0] = '\0';
    if ((inLength = obCommunication.inReceive(&obCommunication, strAux, pobPacket->inReceiveBuffSize, inTimeout, RECEIVING_MSG21)) < 0) {
        pobProtocol->chChar = '\0';
        if (inLength == E_NOCARRIER)
            pobProtocol->fError = VS_FALSE;
        else
            pobProtocol->fError = VS_TRUE;  /* Error State for errors and time out */
    } else {
        pobProtocol->chChar = strAux[0];
        pobProtocol->fError = VS_FALSE;  /* Next State for everything else */
    }

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inReceivePacketWithDisconnect |
*       Accepts the reception of the packet before the disconnection
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inReceivePacketWithDisconnect(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    int inBytesRead,
    inAdjustedBufferSize;
    unsigned char * pchEndOfBuffer;
    char chEndOfPacket;
    char szStatusMsg[MESSAGE_SIZE];
    int inTimeout;


    // pdebug(("--inReceivePacketWithDisconnect--"));

    if (!obCommunication.inReceive)
        return(VS_SUCCESS);

    pobPacket->inReceiveSize = 0;
    pobPacket->pchReceiveBuff[0] = '\0';
    pchEndOfBuffer = pobPacket->pchReceiveBuff;
    inAdjustedBufferSize = pobPacket->inReceiveBuffSize;


    vdGetMessageFromThisFile(PROTOCOL_MSG_FILE, WAITING_FOR_RESPONSE_MSG, szStatusMsg);
    vdDisplayStatusString(szStatusMsg);
    /* calc required for ACT library function (xmdm_receive_data)*/
    inTimeout = pobProtocol->srPET.shTimeOut * 100;

    do {
        if ((inBytesRead = obCommunication.inReceive(&obCommunication, (char *) pchEndOfBuffer, inAdjustedBufferSize, inTimeout, RECEIVING_MSG21)) < 0 && inBytesRead != E_NOCARRIER)
            return(VS_ERROR);

        if (inBytesRead == E_NOCARRIER) {
            if (pobPacket->pchReceiveBuff[0] != STX)
                return(VS_ERROR);

            for (inBytesRead = 0; pobPacket->pchReceiveBuff[inBytesRead] != pobProtocol->srPET.shParameter; inBytesRead++)
                ;
            inBytesRead += 2;           /* including LRC */
            pobProtocol->fError = VS_TRUE;
        } else
            pobProtocol->fError = VS_FALSE;

        pobPacket->inReceiveSize += inBytesRead;
        pchEndOfBuffer += inBytesRead;
        *pchEndOfBuffer = 0;
        if (pobPacket->inReceiveSize > 2) {
            switch (pobProtocol->srPET.shParameter) {
            case STX_ETX_LRC:
                chEndOfPacket = ETX;
                break;
            case STX_ETB_LRC:
                chEndOfPacket = ETB;
                break;
            case SI_SO_LRC:
                chEndOfPacket = SO;
                break;
            default:
                return(VS_SUCCESS);
            }

            if (pobPacket->pchReceiveBuff[pobPacket->inReceiveSize - 2] == chEndOfPacket)
                return(VS_SUCCESS);
        }

        inAdjustedBufferSize -= inBytesRead;
    } while (1);
}

/*********************************************************************************************
* @func int | inSkipRecord |
*        Checks the skip flag in the packet object if it is true, sets the flag
*        to false and sets the error flag in the protocol object to true
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inSkipRecord(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    // pdebug(("--inSkipRecord--"));

    if (pobPacket->fSkip == VS_TRUE) {
        // pdebug(("fSkip true"));
        pobPacket->fSkip = VS_FALSE;
        pobProtocol->fError = VS_TRUE;
    }

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inWaitDelay |
*        Waits the time in seconds defined in the parameter field in the state record
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_ERR or VS_SUCCESS
* @end
**********************************************************************************************/

int inWaitDelay(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    SVC_WAIT(pobProtocol->srPET.shParameter * 100);
    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inSetRetry |
*       Set the pobTran->fRetry so that the user will be prompted for retry if the transaction
*       allows retry.
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_SUCCESS
* @end
**********************************************************************************************/

int inSetRetry(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    TRANSACTION_OBJECT* pobTran;

    // pdebug(("--inSetRetry--"));
    pobTran = (TRANSACTION_OBJECT *) pobPacket->Transaction;
    pobTran->fRetry = VS_TRUE;

    return(VS_SUCCESS);
}



/*********************************************************************************************
* @func int | inResetRetry |
*       Set the pobTran->fRetry so that the user will be prompted for retry if the transaction
*       allows retry.
*
* @parm PROTOCOL_OBJECT * |pobProtocol |
*       Protocol object
*
* @parm PACKET_OBJECT * |pobPacket |
*       Packet object
*
* @rdesc return values.
* @flag int |  VS_SUCCESS
* @end
**********************************************************************************************/

int inResetRetry(PROTOCOL_OBJECT* pobProtocol,PACKET_OBJECT* pobPacket) {
    TRANSACTION_OBJECT* pobTran;

    // pdebug(("--inResetRetry--"));
    pobTran = (TRANSACTION_OBJECT *) pobPacket->Transaction;
    pobTran->fRetry = VS_FALSE;

    return(VS_SUCCESS);
}

/*@func Function that changes the value of obProtocol.fContinue, according to the value of
  obProtocol.srPRT.shParameter.
  @parm PROTOCOL_OBJECT | *obProtocol | Protocol Record Information.
  @parm PACKET_OBJECT | *obPacket | Packet Record Information.
  @rdesc <t int> VS_SUCCESS.
  @comm <nl>
  <t Modifications:>
  <t 11/02/99><tab> Alvaro Marcotrigiano<nl>
  Creation.
 */
int inSetContinueFlag(PROTOCOL_OBJECT* obProtocol,PACKET_OBJECT* obPacket) {
    obProtocol->fContinue = obProtocol->srPET.shParameter;

    return (VS_SUCCESS);
}

int inEndCounterRecords(PROTOCOL_OBJECT* obProtocol,PACKET_OBJECT* obPacket) {
#ifdef COUNTERS
    int inRecord;
    int inRecordsNumber;

    inRecord = inGetStatisticsParm();
    inRecordsNumber = inGetNumberOfConfRecs(szGlobalCNTFileName, SIZE_CNT_REC);

    if (inRecord <= 0 || inRecord > inRecordsNumber) {
        inRecord = 0;
        vdPutStatisticsParm(inRecord);
    }

    if (inRecord >= inRecordsNumber) {
        obProtocol->fError = VS_FALSE;
        vdClearStatisticsParm();
    } else
        obProtocol->fError = VS_TRUE;

#endif /*COUNTERS*/

    return(VS_SUCCESS);
} /* inEndCounterRecords */


FUNCTION_TABLE srProtocolFuncs[] = {
    {inSubroutine,                  SUBROUTINE},
    {inEndSubroutine,               END_SUBROUTINE},
    {inEnd,                         END_PROTOCOL},
    {inErrorProtocol,               ERROR_PROTOCOL},
    {inReceivePacket,               RECEIVE_PACKET},
    {inFramePacket,                 FRAME_PACKET},
    {inSendPacket,                  SEND_PACKET},
    {inEndofBatch,                  END_OF_BATCH},
    {inCheckPacketLRC,              CHECK_PACKET_LRC},
    {inMakePacket,                  MAKE_PACKET},
    {inSendAChar,                   SEND_CHAR},
    {inReceiveChar,                 RECEIVE_CHAR},
    {inReceiveAnyChar,              RECV_ANY_CHAR},
    {inBranchOnChar,                BRANCH_ON_CHAR},
    {inResetCounter,                RESET_COUNTER},
    {inIncrementCounter,            INC_COUNTER},
    {inResetRecordNumber,           RESET_RECORD},
    {inIncrementRecordNumber,       INC_RECORD},
    {inTestRecordNumber,            TEST_RECORD },
    {inDismantlePacket,             DISMANTLE_PACKET},
    {inClearRecvBuff,               CLEAR_RECV_BUFF},
    {inDeFramePacket,               DEFRAME_PACKET},
    {inPause,                       PAUSE},
    {inEndOfDownload,               END_OF_DOWNLOAD},
    {inAnalysePacket,               ANALYSE_PACKET},
    {inTimeOutReceiveAnyChar,       TIMEOUTRECV_ANY_CHAR},
    {inGiveErrorReceiveAnyChar,     ERRORSRECV_ANY_CHAR},
    {inReceivePacketWithDisconnect, RECEIVEWITHDISC_PACKET},
    {inSkipRecord,                  SKIP_RECORD},
    {inWaitDelay,                   WAIT_DELAY },
    {inReceiveHotelLanPacket,       RECV_HOTEL_LAN_PACKET},
    {inSetRetry,                    SET_RETRY},
    {inResetRetry,                  RESET_RETRY},
    {inSetContinueFlag,             SET_CONTINUE_FLAG},
    {inEndCounterRecords,           END_COUNTER_RECORDS},
    {inSetProtoError,               SET_PROTO_ERROR},
    {inPackUnpackWithRetry,         PACK_UNPACK_WITH_RETRY},
    {inPackUnpackForSettlement,     PACK_UNPACK_FOR_SETTLE},
    {inPackUnpackNoRetry,           PACK_UNPACK_NO_RETRY},
    {0,                             END_OF_FUNC_TABLE},

};

/*********************************************************************************************
* @func int | inAddProtocolFunctions |
*       Adds the protocol functions to the flexi record
*
* @end
**********************************************************************************************/

int inAddProtocolFunctions() {
    int inCount = 0;
    do {
        inAddFunctionPointer(srProtocolFuncs[inCount].inFieldID, srProtocolFuncs[inCount].pinFunction);
        inCount++;
    } while (srProtocolFuncs[inCount].inFieldID != END_OF_FUNC_TABLE);

    return(VS_SUCCESS);
}

#undef PROTFUNC_C

#endif //PET_DEFINED

